package com.bocloud.cmp.service.utils;

import static io.fabric8.kubernetes.client.internal.SerializationUtils.dumpWithoutRuntimeStateAsYaml;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.bocloud.cmp.dao.app.OpenshiftClusterDao;
import com.bocloud.cmp.entity.app.resource.OpenshiftCluster;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.ssh.SSH;
import com.bocloud.common.utils.ListTool;
import com.fasterxml.jackson.core.JsonProcessingException;

import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.ContainerStateWaiting;
import io.fabric8.kubernetes.api.model.ContainerStatus;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Namespace;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Quantity;
import io.fabric8.kubernetes.api.model.ReplicationController;
import io.fabric8.kubernetes.api.model.ReplicationControllerBuilder;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.extensions.CPUTargetUtilization;
import io.fabric8.kubernetes.api.model.extensions.Deployment;
import io.fabric8.kubernetes.api.model.extensions.HorizontalPodAutoscaler;
import io.fabric8.kubernetes.api.model.extensions.ReplicaSet;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.openshift.client.DefaultOpenShiftClient;

/**
 * openshift/k8s资源操作工具类
 *
 * @author zjm
 */
@Component("openshiftUtil")
public class OpenshiftUtil {

	private static final String OPENSHIFT_PORT = "8443";
	private static final String HTTPS_PROXY = "https://";

	/**
	 * 江苏银行特殊属性，升级后检查rc健康的超时时间
	 */
	@Value("${k8s.resource.timeout}")
	private Integer k8sResourceTimeout;
	/**
	 * k8s资源默认的命名空间
	 */
	public static final String DEFAULT_NAMESPACE = "default";
	static final String DEPLOYMENT_KEY = "deployment";
	/**
	 * 对所有k8s的资源组件追加一个label，并固定label的key值，value值是应用名，便于按照应用查找组件
	 */
	public static final String UNIFIED_LABEL_KEY = "UNIFIED_APP_NAME";
	/**
	 * 对所有k8s的资源组件追加一个label，并固定label的key值，value值是应用名-随机数，防止资源label完全相同
	 */
	public static final String DIFF_LABEL_KEY = "DIFF_APP_NAME";

	private static final Logger logger = LoggerFactory.getLogger(OpenshiftUtil.class);

	@Autowired
	private OpenshiftClusterDao openshiftClusterDao;

	public class TwoTuple<A, B> {
		public final A first;
		public final B second;

		public TwoTuple(A a, B b) {
			first = a;
			second = b;
		}

		public String toString() {
			return "(" + first + ", " + second + ")";
		}
	}

	/**
	 * 通过openshift获取kubernetes客户端
	 *
	 * @return BsmResult
	 * @author zjm
	 */
	public KubernetesClient getKubernetesClient(String proxyUrl) {
		String master = HTTPS_PROXY + proxyUrl + ":" + OPENSHIFT_PORT;
		try {
			OpenshiftCluster cluster = openshiftClusterDao.getOpenshiftClusterByproxyUrl(proxyUrl);
			Config config = new ConfigBuilder().withMasterUrl(master).build();
			config.setTrustCerts(true);
			config.setOauthToken(cluster.getToken());
			return new DefaultOpenShiftClient(config);
		} catch (Exception e) {
			logger.error("获取[" + master + "]连接失败", e);
			return null;
		}
	}

	/**
	 * 创建k8s service
	 *
	 * @param service
	 *            service
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult createService(String proxyUrl, Service service) {
		Service createService;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			createService = client.services().create(service);
		} catch (KubernetesClientException e) {
			logger.error("service name [" + service.getMetadata().getName() + "]创建失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "service name [" + service.getMetadata().getName() + "]创建失败: " + error);
		} catch (Exception e) {
			logger.error("service name [" + service.getMetadata().getName() + "]创建失败: ", e);
			return new BsmResult(false,
					"service name [" + service.getMetadata().getName() + "]创建失败: " + e.getMessage());
		}
		if (null == createService) {
			return new BsmResult(false, "service name [" + service.getMetadata().getName() + "]创建失败！");
		}
		return new BsmResult(true, createService, "service name [" + createService.getMetadata().getName() + "]创建成功！");
	}

	/**
	 * 创建或替换k8s service
	 *
	 * @param service
	 *            service
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult createOrReplaceService(String proxyUrl, Service service) {
		Service createService;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			createService = client.services().createOrReplace(service);
		} catch (KubernetesClientException e) {
			logger.error("service name [" + service.getMetadata().getName() + "]创建失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "service name [" + service.getMetadata().getName() + "]创建失败: " + error);
		} catch (Exception e) {
			logger.error("service name [" + service.getMetadata().getName() + "]创建失败: ", e);
			return new BsmResult(false,
					"service name [" + service.getMetadata().getName() + "]创建失败: " + e.getMessage());
		}
		if (null == createService) {
			return new BsmResult(false, "service name [" + service.getMetadata().getName() + "]创建失败！");
		}
		return new BsmResult(true, createService, "service name [" + createService.getMetadata().getName() + "]创建成功！");
	}

	/**
	 * 创建k8s rc
	 *
	 * @param replicationController
	 *            replicationController
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult createReplicationController(String proxyUrl, ReplicationController replicationController) {
		ReplicationController createReplicationController;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			createReplicationController = client.replicationControllers().create(replicationController);
		} catch (KubernetesClientException e) {
			logger.error("replicationController name [" + replicationController.getMetadata().getName() + "]创建失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false,
					"replicationController name [" + replicationController.getMetadata().getName() + "]创建失败: " + error);
		} catch (Exception e) {
			logger.error("replicationController name [" + replicationController.getMetadata().getName() + "]创建失败: ", e);
			return new BsmResult(false, "replicationController name [" + replicationController.getMetadata().getName()
					+ "]创建失败: " + e.getMessage());
		}
		if (null == createReplicationController) {
			return new BsmResult(false,
					"replicationController name [" + replicationController.getMetadata().getName() + "]创建失败！");
		}
		return new BsmResult(true, createReplicationController,
				"replicationController name [" + createReplicationController.getMetadata().getName() + "]创建成功！");
	}

	/**
	 * 创建或者替换k8s rc
	 *
	 * @param replicationController
	 *            replicationController
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult createOrReplaceReplicationController(String proxyUrl,
			ReplicationController replicationController) {
		ReplicationController createReplicationController;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			createReplicationController = client.replicationControllers().createOrReplace((replicationController));
		} catch (KubernetesClientException e) {
			logger.error("replicationController name [" + replicationController.getMetadata().getName() + "]替换失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false,
					"replicationController name [" + replicationController.getMetadata().getName() + "]替换失败: " + error);
		} catch (Exception e) {
			logger.error("replicationController name [" + replicationController.getMetadata().getName() + "]替换失败: ", e);
			return new BsmResult(false, "replicationController name [" + replicationController.getMetadata().getName()
					+ "]替换失败: " + e.getMessage());
		}
		if (null == createReplicationController) {
			return new BsmResult(false,
					"replicationController name [" + replicationController.getMetadata().getName() + "]替换失败！");
		}
		return new BsmResult(true, createReplicationController,
				"replicationController name [" + createReplicationController.getMetadata().getName() + "]替换成功！");
	}

	/**
	 * 创建k8s deployment
	 *
	 * @param deployment
	 *            deployment
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult createDeployment(String proxyUrl, Deployment deployment) {
		Deployment createDeployment = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			createDeployment = client.extensions().deployments().create(deployment);
		} catch (KubernetesClientException e) {
			logger.error("deployment name [" + deployment.getMetadata().getName() + "]创建失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "deployment name [" + deployment.getMetadata().getName() + "]创建失败: " + error);
		} catch (Exception e) {
			logger.error("deployment name [" + deployment.getMetadata().getName() + "]创建失败: ", e);
			return new BsmResult(false,
					"deployment name [" + deployment.getMetadata().getName() + "]创建失败: " + e.getMessage());
		}
		if (null == createDeployment) {
			return new BsmResult(false, "deployment name [" + deployment.getMetadata().getName() + "]创建失败！");
		}
		return new BsmResult(true, createDeployment,
				"deployment name [" + createDeployment.getMetadata().getName() + "]创建成功！");
	}

	/**
	 * 创建HPA控制器
	 *
	 * @param labels
	 *            labels
	 * @param hpaName
	 *            hpaName
	 * @param resourceKind
	 *            控制资源的Kind
	 * @param resourceName
	 *            控制资源的名称
	 * @param minReplicas
	 *            最小实例数
	 * @param maxReplicas
	 *            最大实例数
	 * @param cpuTargetUtilization
	 *            cpu百分比（比如：填写50，cpu的百分比为50%）
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult createHPA(String proxyUrl, Map<String, String> labels, String hpaName, String resourceKind,
			String namespace, String resourceName, int minReplicas, int maxReplicas, int cpuTargetUtilization) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		HorizontalPodAutoscaler hpa;
		try {
			hpa = client.extensions().horizontalPodAutoscalers().createOrReplaceWithNew().withNewMetadata()
					.withNamespace(namespace).withName(hpaName).addToLabels(labels).endMetadata().withNewSpec()
					.withNewScaleRef().withName(resourceName).withKind(resourceKind).endScaleRef()
					.withMinReplicas(minReplicas).withMaxReplicas(maxReplicas)
					.withCpuUtilization(new CPUTargetUtilization(cpuTargetUtilization)).endSpec().done();
		} catch (KubernetesClientException e) {
			logger.error("horizontalPodAutoscaler name[" + hpaName + "]创建失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, null, "horizontalPodAutoscaler name[" + hpaName + "]创建失败: " + error);
		} catch (Exception e) {
			logger.error("horizontalPodAutoscaler name[" + hpaName + "]创建失败: ", e);
			return new BsmResult(false, null, "horizontalPodAutoscaler name[" + hpaName + "]创建失败: " + e.getMessage());
		}
		if (null != hpa) {
			return new BsmResult(true, hpa, "horizontalPodAutoscaler name[" + hpaName + "]创建成功！");
		}
		return new BsmResult(false, "horizontalPodAutoscaler name[" + hpaName + "]创建失败！");
	}

	/**
	 * 按照k8s资源文件创建资源
	 *
	 * @param filePath
	 *            资源路径
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult layoutDeploy(String proxyUrl, String appName, String filePath) {
		logger.info("正在部署[" + filePath + "]...");
		BsmResult bsmResult = new BsmResult();
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			bsmResult.setMessage("获取client[" + proxyUrl + "]连接失败！");
			logger.error(bsmResult.getMessage());
			return bsmResult;
		}
		try {
			// 最终需要添加的资源
			List<HasMetadata> hasMetadatas = new ArrayList<>();
			// 获取文件中资源
			List<HasMetadata> resourceList = client.load(new FileInputStream(filePath)).get();
			// 设置label value追加的日期和随机字符串
			String diffLabelValue = "-" + RandomStringUtils.randomAlphanumeric(7).toLowerCase();
			for (HasMetadata resource : resourceList) {
				// 判断资源的命名空间是否存在，如果不存在则创建这个命名空间
				if (null == (getNamespace(client, resource.getMetadata().getNamespace()).first)) {
					client.namespaces().createNew().withNewMetadata().withName(resource.getMetadata().getNamespace())
							.endMetadata().done();
				}
				Map<String, String> labels = resource.getMetadata().getLabels();
				if (null == labels) {
					labels = new HashMap<>();
				}
				// 追加资源标签
				labels.put(UNIFIED_LABEL_KEY, appName);
				labels.put(DIFF_LABEL_KEY, appName + diffLabelValue);
				// 如果资源是rc或者deployment则给资源中的pod追加label
				if ("ReplicationController".equals(resource.getKind())) {
					// 如果rc资源已经存在则直接返回不允许创建这个文件
					if (null != getRc(proxyUrl, resource.getMetadata().getNamespace(), resource.getMetadata().getName())
							.getData()) {
						bsmResult.setMessage("应用发布失败！文件中rc，namespace[" + resource.getMetadata().getNamespace()
								+ "],name[" + resource.getMetadata().getName() + "]资源已经存在，不允许发布！");
						logger.error(bsmResult.getMessage());
						return bsmResult;
					}
					ReplicationController replicationController = (ReplicationController) resource;
					// 给rc资源追加label和seletor
					Map<String, String> podLabels = replicationController.getSpec().getTemplate().getMetadata()
							.getLabels();
					if (null == podLabels) {
						podLabels = new HashMap<>();
					}
					// 追加资源标签
					podLabels.put(UNIFIED_LABEL_KEY, appName);
					podLabels.put(DIFF_LABEL_KEY, appName + diffLabelValue);
					Map<String, String> selectors = replicationController.getSpec().getSelector();
					if (null == selectors) {
						selectors = new HashMap<>();
					}
					// 追加资源标签
					selectors.put(UNIFIED_LABEL_KEY, appName);
					selectors.put(DIFF_LABEL_KEY, appName + diffLabelValue);
				} else if ("Service".equals(resource.getKind())) {
					// 如果Service资源已经存在则直接返回不允许创建这个文件
					if (null != getService(proxyUrl, resource.getMetadata().getNamespace(),
							resource.getMetadata().getName()).getData()) {
						bsmResult.setMessage("应用发布失败！文件中Service，namespace[" + resource.getMetadata().getNamespace()
								+ "],name[" + resource.getMetadata().getName() + "]资源已经存在，不允许发布！");
						logger.error(bsmResult.getMessage());
						return bsmResult;
					}
				} else if ("HorizontalPodAutoscaler".equals(resource.getKind())) {
					// 如果HPA资源已经存在则直接返回不允许创建这个文件
					if (null != getHPA(proxyUrl, resource.getMetadata().getNamespace(),
							resource.getMetadata().getName()).getData()) {
						bsmResult.setMessage("应用发布失败！文件中HPA，namespace[" + resource.getMetadata().getNamespace()
								+ "],name[" + resource.getMetadata().getName() + "]资源已经存在，不允许发布！");
						logger.error(bsmResult.getMessage());
						return bsmResult;
					}
				} else {
					bsmResult.setMessage("应用发布失败！暂不支持[" + resource.getKind() + "]该资源类型的发布！");
					logger.error(bsmResult.getMessage());
					return bsmResult;
				}
				hasMetadatas.add(resource);
			}
			resourceList = client.resourceList(hasMetadatas).createOrReplace();
			// 部署后进行健康检查，如果超时时间内没有任何pod是running状态则表示该应用部署失败，并且删除该文件中资源
			for (HasMetadata hasMetadata : resourceList) {
				if ("ReplicationController".equals(hasMetadata.getKind())) {
					ReplicationController rc = (ReplicationController) hasMetadata;
					if (!(bsmResult = checkRcRunning(proxyUrl, rc)).isSuccess()) {
						bsmResult.setMessage("文件[" + filePath + "]部署失败，rc[" + rc.getMetadata().getName() + "]运行失败！");
						if ((deleteLayoutDeploy(proxyUrl, filePath)).isSuccess()) {
							bsmResult.setMessage(bsmResult.getMessage() + "已删除该文件所有资源");
						} else {
							bsmResult.setMessage(bsmResult.getMessage() + "该文件所有资源删除失败，请手动删除");
						}
						logger.error(bsmResult.getMessage());
						return bsmResult;
					}
				}
			}
			bsmResult.setMessage("文件[" + filePath + "]部署成功！");
			bsmResult.setSuccess(true);
			bsmResult.setData(resourceList);
			logger.info(bsmResult.getMessage());
			return bsmResult;
		} catch (FileNotFoundException e) {
			bsmResult.setMessage("文件 [" + filePath + "]未找到: " + e);
			logger.error(bsmResult.getMessage());
			// 报异常后需要删除发布的资源
		} catch (KubernetesClientException e) {
			String error = getErrorInfo(e);
			bsmResult.setMessage("发布应用失败: " + error);
			logger.error("发布应用失败: ", e);
		} catch (Exception e) {
			bsmResult.setMessage("发布应用失败: " + e);
			logger.error(bsmResult.getMessage());
		}
		// 如果部署失败则需要删除该部署文件中的所有资源
		deleteLayoutDeploy(proxyUrl, filePath);
		bsmResult.setMessage(bsmResult.getMessage() + "已删除该文件中所有资源");
		logger.error(bsmResult.getMessage());
		return bsmResult;
	}

	/**
	 * 按照k8s资源文件获取资源
	 *
	 * @param yaml
	 *            资源文件
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getResourceByYaml(String proxyUrl, String yaml) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			// 获取文件中资源
			List<HasMetadata> resourceList = client.load(new ByteArrayInputStream(yaml.getBytes())).get();
			return new BsmResult(true, resourceList, "获取文件[" + yaml + "]资源成功！");
		} catch (KubernetesClientException e) {
			logger.error("获取文件[" + yaml + "]资源失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取文件[" + yaml + "]资源失败: " + error);
		} catch (Exception e) {
			logger.error("获取文件[" + yaml + "]资源失败: ", e);
			return new BsmResult(false, "获取文件[" + yaml + "]资源失败: " + e.getMessage());
		}
	}

	/**
	 * 按照k8s资源字符串创建资源
	 *
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult layoutDeployByYaml(String proxyUrl, String yaml) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		List<HasMetadata> resourceList = client.load(new ByteArrayInputStream(yaml.getBytes())).createOrReplace();
		if (!ListTool.isEmpty(resourceList)) {
			logger.info("文件\n" + yaml + "\n部署成功! ");
			return new BsmResult(true, "部署成功！");
		}
		logger.error("文件\n" + yaml + "\n部署失败! ");
		return new BsmResult(false, "部署失败！");
	}

	/**
	 * 删除k8s service集合
	 *
	 * @param services
	 *            services
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult deleteServices(String proxyUrl, List<Service> services) {
		if (ListTool.isEmpty(services)) {
			return new BsmResult(false, "需要删除service资源为空！");
		}
		boolean result = false;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			result = client.services().delete(services);
		} catch (KubernetesClientException e) {
			logger.error("service资源删除失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "service资源删除失败: " + error);
		} catch (Exception e) {
			logger.error("service资源删除失败: ", e);
			return new BsmResult(false, "service资源删除失败: " + e.getMessage());
		}
		if (result) {
			return new BsmResult(true, "service资源删除成功！");
		}
		return new BsmResult(false, "service资源删除失败！");
	}

	/**
	 * 删除k8s service集合
	 *
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult deleteService(String proxyUrl, Service service) {
		List<Service> services = new LinkedList<>();
		services.add(service);
		return deleteServices(proxyUrl, services);
	}

	/**
	 * 删除k8s deployment集合
	 *
	 * @param deployments
	 *            deployments
	 * @author zjm
	 * @date 2017年3月17日
	 */
	public BsmResult deleteDeployments(String proxyUrl, List<Deployment> deployments) {
		if (ListTool.isEmpty(deployments)) {
			return new BsmResult(false, "需要删除deployments资源为空！");
		}
		boolean result = false;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			result = client.extensions().deployments().delete(deployments);
		} catch (KubernetesClientException e) {
			logger.error("deployment资源删除失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "deployment资源删除失败: " + error);
		} catch (Exception e) {
			logger.error("deployment资源删除失败: ", e);
			return new BsmResult(false, "deployment资源删除失败: " + e.getMessage());
		}
		if (result) {
			return new BsmResult(true, "replicationController资源删除成功！");
		}
		return new BsmResult(false, "deployment资源删除失败！");
	}

	/**
	 * 删除k8s rc集合
	 *
	 * @author zjm
	 * @date 2017年3月17日
	 */
	public BsmResult deleteReplicationControllers(String proxyUrl, List<ReplicationController> replicationControllers) {
		if (ListTool.isEmpty(replicationControllers)) {
			return new BsmResult(false, "需要删除replicationControllers资源为空！");
		}
		boolean result;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			result = client.replicationControllers().delete(replicationControllers);
		} catch (KubernetesClientException e) {
			logger.error("replicationController资源删除失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "replicationController资源删除失败: " + error);
		} catch (Exception e) {
			logger.error("replicationController资源删除失败: ", e);
			return new BsmResult(false, "replicationController资源删除失败: " + e.getMessage());
		}
		if (result) {
			return new BsmResult(true, "replicationController资源删除成功！");
		}
		return new BsmResult(false, "replicationController资源删除失败！");
	}

	/**
	 * 删除k8s rc集合
	 *
	 * @author zjm
	 * @date 2017年3月17日
	 */
	public BsmResult deleteReplicationController(String proxyUrl, ReplicationController replicationController) {
		if (null == replicationController) {
			return new BsmResult(false, "需要删除replicationControllers资源为空！");
		}
		boolean result;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			result = client.replicationControllers().delete(replicationController);
		} catch (KubernetesClientException e) {
			logger.error("replicationController资源删除失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "replicationController资源删除失败: " + error);
		} catch (Exception e) {
			logger.error("replicationController资源删除失败: ", e);
			return new BsmResult(false, "replicationController资源删除失败: " + e.getMessage());
		}
		if (result) {
			return new BsmResult(true, "replicationController资源删除成功！");
		}
		return new BsmResult(false, "replicationController资源删除失败！");
	}

	/**
	 * 删除k8s pod集合
	 *
	 * @author zjm
	 * @date 2017年4月1日
	 */
	public BsmResult deletePods(String proxyUrl, List<Pod> pods) {
		if (ListTool.isEmpty(pods)) {
			return new BsmResult(false, "需要删除pods资源为空！");
		}
		boolean result = false;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			result = client.pods().delete(pods);
		} catch (KubernetesClientException e) {
			logger.error("pod资源删除失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "pod资源删除失败: " + error);
		} catch (Exception e) {
			logger.error("pod资源删除失败: ", e);
			return new BsmResult(false, "pod资源删除失败: " + e.getMessage());
		}
		if (result) {
			return new BsmResult(true, "pod资源删除成功！");
		}
		return new BsmResult(false, "pod资源删除失败！");
	}

	/**
	 * 删除k8s hpa集合
	 *
	 * @author zjm
	 * @date 2017年4月9日
	 */
	public BsmResult deleteHPAs(String proxyUrl, List<HorizontalPodAutoscaler> hpas) {
		if (ListTool.isEmpty(hpas)) {
			return new BsmResult(false, "需要删除hpas资源为空！");
		}
		boolean result;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			result = client.extensions().horizontalPodAutoscalers().delete(hpas);
		} catch (KubernetesClientException e) {
			logger.error("弹性伸缩删除失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "弹性伸缩删除失败: " + error);
		} catch (Exception e) {
			logger.error("弹性伸缩删除失败: ", e);
			return new BsmResult(false, "弹性伸缩删除失败: " + e.getMessage());
		}
		if (result) {
			return new BsmResult(true, "弹性伸缩删除成功！");
		}
		return new BsmResult(false, "弹性伸缩删除失败！");
	}

	/**
	 * 按照k8s资源文件删除资源
	 *
	 * @param filePath
	 *            资源路径
	 * @author zjm
	 * @date 2017年3月17日
	 */
	public BsmResult deleteLayoutDeploy(String proxyUrl, String filePath) {
		if (StringUtils.isBlank(filePath)) {
			return new BsmResult(false, "文件[" + filePath + "]未找到，删除失败！");
		}
		boolean result;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			result = client.load(new FileInputStream(filePath)).delete();
		} catch (FileNotFoundException e) {
			logger.error("文件 [" + filePath + "]未找到，删除失败: ", e);
			return new BsmResult(false, "文件 [" + filePath + "]未找到，删除失败: " + e);
		} catch (KubernetesClientException e) {
			logger.error("删除文件 [" + filePath + "]资源失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "删除文件 [" + filePath + "]资源失败: " + error);
		} catch (Exception e) {
			logger.error("删除文件 [" + filePath + "]资源失败: ", e);
			return new BsmResult(false, "删除文件 [" + filePath + "]资源失败: " + e.getMessage());
		}
		if (!result) {
			return new BsmResult(false, "文件[" + filePath + "]未找到，删除失败！");
		}
		return new BsmResult(true, "文件[" + filePath + "]删除成功！");
	}

	/**
	 * 变更k8s rc实例数
	 *
	 * @param name
	 *            rc的名字
	 * @param count
	 *            变更的数量
	 * @author zjm
	 * @date 2017年3月17日
	 */
	public BsmResult scaleRc(String proxyUrl, String namespace, String name, int count) {
		logger.info("scale rc start...");
		BsmResult bsmResult = new BsmResult();
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			bsmResult.setMessage("获取client[" + proxyUrl + "]连接失败！");
			logger.error(bsmResult.getMessage());
			return bsmResult;
		}
		try {
			client.replicationControllers().inNamespace(namespace).withName(name).scale(count);
		} catch (KubernetesClientException e) {
			logger.error("[" + name + "]实例变更为[" + count + "]失败: ", e);
			String error = getErrorInfo(e);
			bsmResult.setMessage("[" + name + "]实例变更为[" + count + "]失败: " + error);
			return bsmResult;
		} catch (Exception e) {
			bsmResult.setMessage("[" + name + "]实例变更为[" + count + "]失败: " + e);
			logger.error(bsmResult.getMessage());
			return bsmResult;
		}
		logger.info("scale rc success.");
		bsmResult.setSuccess(true);
		bsmResult.setMessage("[" + name + "]实例变更为[" + count + "]成功！");
		return bsmResult;
	}

	/**
	 * 按照名称获取rc
	 *
	 * @author zjm
	 * @date 2017年4月1日
	 */
	public BsmResult getRc(String proxyUrl, String namespace, String name) {
		ReplicationController rc = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			rc = client.replicationControllers().inNamespace(namespace).withName(name).get();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的rc失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取namespace[" + namespace + "], name[" + name + "]的rc失败: " + error);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的rc失败: ", e);
			return new BsmResult(false, "获取namespace[" + namespace + "], name[" + name + "]的rc失败: " + e.getMessage());
		}
		if (null == rc) {
			return new BsmResult(true, "获取namespace[" + namespace + "], name[" + name + "]的rc为空！");
		}
		return new BsmResult(true, rc, "获取namespace[" + namespace + "], name[" + name + "]的rc成功！");
	}

	/**
	 * 获取k8s rc集合
	 *
	 * @author zjm
	 * @date 2017年3月22日
	 */
	public BsmResult getRcs(String proxyUrl, Map<String, String> labels) {
		List<ReplicationController> rcs = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			rcs = client.replicationControllers().inAnyNamespace().withLabels(labels).list().getItems();
		} catch (KubernetesClientException e) {
			logger.error("获取label[" + labels.toString() + "]的rc集合失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取label[" + labels.toString() + "]的rc集合失败: " + error);
		} catch (Exception e) {
			logger.error("获取label[" + labels.toString() + "]的rc集合失败: ", e);
			return new BsmResult(false, "获取label[" + labels.toString() + "]的rc集合失败: " + e.getMessage());
		}
		if (ListTool.isEmpty(rcs)) {
			return new BsmResult(true, "获取label[" + labels.toString() + "]的rc集合为空！");
		}
		return new BsmResult(true, rcs, "获取label[" + labels.toString() + "]的rc集合成功！");
	}

	/**
	 * 按照名称获取service
	 *
	 * @author zjm
	 * @date 2017年4月1日
	 */
	public BsmResult getService(String proxyUrl, String namespace, String name) {
		Service service = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			service = client.services().inNamespace(namespace).withName(name).get();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的service失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取namespace[" + namespace + "], name[" + name + "]的service失败: " + error);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的service失败: ", e);
			return new BsmResult(false,
					"获取namespace[" + namespace + "], name[" + name + "]的service失败: " + e.getMessage());
		}
		if (null == service) {
			return new BsmResult(true, "获取namespace[" + namespace + "], name[" + name + "]的service为空！");
		}
		return new BsmResult(true, service, "获取namespace[" + namespace + "], name[" + name + "]的service成功！");
	}

	/**
	 * 按照labels获取k8s service集合
	 *
	 * @param labels
	 *            labels
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getServices(String proxyUrl, Map<String, String> labels) {
		List<Service> services = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			services = client.services().inAnyNamespace().withLabels(labels).list().getItems();
		} catch (KubernetesClientException e) {
			logger.error("获取label[" + labels.toString() + "]的service失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取label[" + labels.toString() + "]的service失败: " + error);
		} catch (Exception e) {
			logger.error("获取label[" + labels.toString() + "]的service失败: ", e);
			return new BsmResult(false, "获取label[" + labels.toString() + "]的service失败: " + e.getMessage());
		}
		if (ListTool.isEmpty(services)) {
			return new BsmResult(true, "获取label[" + labels.toString() + "]的service为空！");
		}
		return new BsmResult(true, services, "获取label[" + labels.toString() + "]的service成功！");
	}

	/**
	 * 按照namespace获取k8s service集合
	 *
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getServicesByNamespace(String proxyUrl, String namespace) {
		List<Service> services = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			services = client.services().inNamespace(namespace).list().getItems();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "]的service失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取namespace[" + namespace + "]的service失败: " + error);
		} catch (Exception e) {
			logger.error("获取label[" + namespace + "]的service失败: ", e);
			return new BsmResult(false, "获取namespace[" + namespace + "]的service失败: " + e.getMessage());
		}
		if (ListTool.isEmpty(services)) {
			return new BsmResult(true, "获取namespace[" + namespace + "]的service为空！");
		}
		return new BsmResult(true, services, "获取namespace[" + namespace + "]的service成功！");
	}

	/**
	 * 获取k8s deployment
	 *
	 * @param name
	 *            name
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getDeployment(String proxyUrl, String namespace, String name) {
		Deployment deployment = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			deployment = client.extensions().deployments().inNamespace(namespace).withName(name).get();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "]中, name[" + name + "]的deployment失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取namespace[" + namespace + "]中, name[" + name + "]的deployment失败: " + error);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "]中, name[" + name + "]的deployment失败: ", e);
			return new BsmResult(false,
					"获取namespace[" + namespace + "]中, name[" + name + "]的deployment失败: " + e.getMessage());
		}
		if (null == deployment) {
			return new BsmResult(true, "获取namespace[" + namespace + "]中, name[" + name + "]的deployment为空！");
		}
		return new BsmResult(true, deployment, "获取namespace[" + namespace + "]中, name[" + name + "]的deployment成功！");
	}

	/**
	 * 获取k8s deployment集合
	 *
	 * @author zjm
	 * @date 2017年3月22日
	 */
	public BsmResult getDeployments(String proxyUrl, Map<String, String> labels) {
		List<Deployment> deployments = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			deployments = client.extensions().deployments().inAnyNamespace().withLabels(labels).list().getItems();
		} catch (KubernetesClientException e) {
			logger.error("获取label[" + labels.toString() + "]的deployment集合失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取label[" + labels.toString() + "]的deployment集合失败: " + error);
		} catch (Exception e) {
			logger.error("获取label[" + labels.toString() + "]的deployment集合失败: ", e);
			return new BsmResult(false, "获取label[" + labels.toString() + "]的deployment集合失败: " + e.getMessage());
		}
		if (ListTool.isEmpty(deployments)) {
			return new BsmResult(true, "获取label[" + labels.toString() + "]的deployment集合为空！");
		}
		return new BsmResult(true, deployments, "获取label[" + labels.toString() + "]的deployment集合成功！");
	}

	/**
	 * 获取k8s pod
	 *
	 * @author zjm
	 */
	public TwoTuple<Pod, String> getPod(String proxyUrl, String namespace, String name) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new TwoTuple<>(null, "获取client[" + proxyUrl + "]连接失败！");
		}
		return getPod(client, namespace, name);
	}

	public TwoTuple<Pod, String> getPod(KubernetesClient client, String namespace, String name) {
		Pod pod = null;
		String info = null;
		try {
			pod = client.pods().inNamespace(namespace).withName(name).get();
			if (pod == null) {
				info = "获取namespace[" + namespace + "], name[" + name + "]的pod为空！";
			}
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的pod失败: ", e);
			info = "获取namespace[" + namespace + "], name[" + name + "]的pod失败: " + getErrorInfo(e);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的pod失败: ", e);
			info = "获取namespace[" + namespace + "], name[" + name + "]的pod失败: " + e.getMessage();
		}
		return new TwoTuple<>(pod, info);
	}

	private String getErrorInfo(KubernetesClientException e) {
		if (null != e.getStatus()) {
			return e.getStatus().getMessage();
		} else if (null != e.getCause()) {
			return e.getCause().getMessage();
		} else {
			return e.getMessage();
		}
	}

	/**
	 * 获取k8s pod集合
	 *
	 * @param proxyUrl
	 *            proxyUrl
	 * @param labels
	 *            labels
	 * @return BsmResult
	 * @author zjm
	 */
	public TwoTuple<List<Pod>, String> getPods(String proxyUrl, Map<String, String> labels) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new TwoTuple<>(null, "获取client[" + proxyUrl + "]连接失败！");
		}
		return getPods(client, labels);
	}

	public TwoTuple<List<Pod>, String> getPods(KubernetesClient client, Map<String, String> labels) {
		List<Pod> pods = null;
		String info = null;
		try {
			pods = client.pods().inAnyNamespace().withLabels(labels).list().getItems();
			if (pods == null || pods.size() == 0) {
				info = "获取label[" + labels.toString() + "]的pod集合为空！";
			}
		} catch (KubernetesClientException e) {
			logger.error("获取label[" + labels.toString() + "]的pod集合失败: ", e);
			info = "获取label[" + labels.toString() + "]的pod集合失败: " + getErrorInfo(e);
		} catch (Exception e) {
			logger.error("获取label[" + labels.toString() + "]的pod集合失败: ", e);
			info = "获取label[" + labels.toString() + "]的pod集合失败: " + e.getMessage();
		}
		return new TwoTuple<>(pods, info);
	}

	/**
	 * 获取k8s hpa
	 *
	 * @param proxyUrl
	 *            proxyUrl
	 * @param namespace
	 *            namespace
	 * @param name
	 *            name
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getHPA(String proxyUrl, String namespace, String name) {
		HorizontalPodAutoscaler hpa;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			hpa = client.extensions().horizontalPodAutoscalers().inNamespace(namespace).withName(name).get();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的弹性伸缩失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取namespace[" + namespace + "], name[" + name + "]的弹性伸缩失败: " + error);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "], name[" + name + "]的弹性伸缩失败: ", e);
			return new BsmResult(false, "获取namespace[" + namespace + "], name[" + name + "]的弹性伸缩失败: " + e.getMessage());
		}
		if (null == hpa) {
			return new BsmResult(false, "获取namespace[" + namespace + "], name[" + name + "]的弹性伸缩失败！");
		}
		return new BsmResult(true, hpa, "获取namespace[" + namespace + "], name[" + name + "]的hpas资源成功！");
	}

	/**
	 * 根据资源label／资源kind和资源名称获取hpa
	 *
	 * @param proxyUrl
	 *            proxyUrl
	 * @param namespace
	 *            namespace
	 * @param labels
	 *            labels
	 * @param resourceKind
	 *            resourceKind
	 * @param resourceName
	 *            resourceName
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getHPA(String proxyUrl, String namespace, Map<String, String> labels, String resourceKind,
			String resourceName) {
		List<HorizontalPodAutoscaler> hpas = null;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			hpas = client.extensions().horizontalPodAutoscalers().inNamespace(namespace).withLabels(labels).list()
					.getItems();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "], labels[" + labels + "]的弹性伸缩失败: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "获取namespace[" + namespace + "], labels[" + labels + "]的弹性伸缩失败: " + error);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "], labels[" + labels + "]的弹性伸缩失败: ", e);
			return new BsmResult(false,
					"获取namespace[" + namespace + "], labels[" + labels + "]的弹性伸缩失败: " + e.getMessage());
		}
		if (!ListTool.isEmpty(hpas)) {
			for (HorizontalPodAutoscaler hpa : hpas) {
				if (hpa.getSpec().getScaleRef().getKind().equals(resourceKind)
						&& hpa.getSpec().getScaleRef().getName().equals(resourceName)) {
					return new BsmResult(true, hpa,
							"获取resourceKind[" + resourceKind + "], resourceName[" + resourceName + "]的弹性伸缩成功！");
				}
			}
		}
		return new BsmResult(false, "获取resourceKind[" + resourceKind + "], resourceName[" + resourceName + "]的弹性伸缩成功！");
	}

	public TwoTuple<List<HorizontalPodAutoscaler>, String> getHPAs(String proxyUrl, Map<String, String> labels) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new TwoTuple<>(null, "获取client[" + proxyUrl + "]连接失败！");
		}
		return getHPAs(client, labels);
	}

	/**
	 * 获取k8s hpa集合
	 *
	 * @param client
	 *            KubernetesClient
	 * @param labels
	 *            labels
	 * @return BsmResult
	 * @author zjm
	 */
	public TwoTuple<List<HorizontalPodAutoscaler>, String> getHPAs(KubernetesClient client,
			Map<String, String> labels) {
		List<HorizontalPodAutoscaler> hpas = null;
		String info = null;
		try {
			hpas = client.extensions().horizontalPodAutoscalers().inAnyNamespace().withLabels(labels).list().getItems();
			if (null == hpas || ListTool.isEmpty(hpas)) {
				info = "获取label[" + labels.toString() + "]的hpa集合为空！";
			}
		} catch (KubernetesClientException e) {
			logger.error("获取label[" + labels.toString() + "]的hpa集合失败: ", e);
			info = "获取label[" + labels.toString() + "]的hpa集合失败: " + getErrorInfo(e);
		} catch (Exception e) {
			logger.error("获取label[" + labels.toString() + "]的hpa集合失败: ", e);
			info = "获取label[" + labels.toString() + "]的hpa集合失败: " + e.getMessage();
		}
		return new TwoTuple<>(hpas, info);
	}

	private TwoTuple<Namespace, String> getNamespace(KubernetesClient client, String name) {
		Namespace namespace = null;
		String info = null;
		try {
			namespace = client.namespaces().withName(name).get();
			if (null == namespace) {
				info = "获取name[" + name + "]的namespace资源失败！";
			}
		} catch (KubernetesClientException e) {
			logger.error("获取name[" + name + "]的namespace资源失败: ", e);
			info = "获取name[" + name + "]的namespace资源失败: " + getErrorInfo(e);
		} catch (Exception e) {
			logger.error("获取name[" + name + "]的namespace资源失败: ", e);
			info = "获取name[" + name + "]的namespace资源失败: " + e.getMessage();
		}
		return new TwoTuple<>(namespace, info);
	}

	/**
	 * 获取符合条件的deployment总实例数
	 *
	 * @param labels
	 *            labels
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getDeploymentsReplicas(String proxyUrl, Map<String, String> labels) {
		int countReplicas = 0;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		List<Deployment> deployments = null;
		try {
			deployments = client.extensions().deployments().inAnyNamespace().withLabels(labels).list().getItems();
		} catch (KubernetesClientException e) {
			logger.error("获取label[" + labels.toString() + "]的deployment集合为空: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(true, "获取label[" + labels.toString() + "]的deployment集合为空: " + error);
		} catch (Exception e) {
			logger.error("获取label[" + labels.toString() + "]的deployment集合为空: ", e);
			return new BsmResult(true, "获取label[" + labels.toString() + "]的deployment集合为空: " + e.getMessage());
		}
		if (ListTool.isEmpty(deployments)) {
			return new BsmResult(true, "获取label[" + labels.toString() + "]的deployment集合为空！");
		}
		for (Deployment deployment : deployments) {
			countReplicas += deployment.getSpec().getReplicas();
		}
		return new BsmResult(true, countReplicas,
				"获取label[" + labels.toString() + "]的deployment的实例数为：" + countReplicas);
	}

	/**
	 * 将资源输出成yaml格式
	 *
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult exportToYaml(String proxyUrl, HasMetadata hasMetadata) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		if (hasMetadata == null || hasMetadata.getMetadata() == null) {
			return new BsmResult(false, "获取资源失败");
		}
		String excute = "";
		SSH ssh = null;
		try {
			OpenshiftCluster cluster = openshiftClusterDao.getOpenshiftClusterByproxyUrl(proxyUrl);
			String masterIp = cluster.getMasterIp();
			String username = cluster.getUsername();
			String password = cluster.getPassword();
			ssh = new SSH(masterIp, username, password);
			if (ssh.connect()) {
				excute = ssh.executeWithResult("oc login -u system:admin; oc get " + hasMetadata.getKind().toLowerCase()
						+ " " + hasMetadata.getMetadata().getName() + " -n " + hasMetadata.getMetadata().getNamespace()
						+ " -o yaml");
				if (excute.contains("Error")) {
					String error = excute.substring(excute.indexOf("Error"));
					logger.error("export result: \n" + error);
					return new BsmResult(false, "资源[" + hasMetadata.getMetadata().getName() + "]未找到: " + error);
				} else {
					excute = excute.substring(excute.indexOf("apiVersion: "));
				}
				logger.info("资源[" + hasMetadata.getMetadata().getName() + "]输出为：\n" + excute);
			}
		} catch (Exception e) {
			return new BsmResult(false, "资源[" + hasMetadata.getMetadata().getName() + "]未找到: " + e);
		} finally {
			ssh.close();
		}
		return new BsmResult(true, excute, "获取资源[" + hasMetadata.getMetadata().getName() + "]成功！");
	}

	/**
	 * 获取符合条件的rc总实例数
	 *
	 * @param labels
	 *            labels
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult getRcsReplicas(String proxyUrl, Map<String, String> labels) {
		int countReplicas = 0;
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		List<ReplicationController> rcs = null;
		try {
			rcs = client.replicationControllers().inAnyNamespace().withLabels(labels).list().getItems();
		} catch (KubernetesClientException e) {
			logger.error("获取label[" + labels.toString() + "]rc集合为空: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(true, "获取label[" + labels.toString() + "]rc集合为空: " + error);
		} catch (Exception e) {
			logger.error("获取label[" + labels.toString() + "]rc集合为空: ", e);
			return new BsmResult(true, "获取label[" + labels.toString() + "]rc集合为空: " + e.getMessage());
		}
		if (ListTool.isEmpty(rcs)) {
			return new BsmResult(true, "获取label[" + labels.toString() + "]rc集合为空！");
		}
		for (ReplicationController rc : rcs) {
			countReplicas += rc.getSpec().getReplicas();
		}
		return new BsmResult(true, countReplicas, "获取label[" + labels.toString() + "]的rc的实例数为：" + countReplicas);
	}

	/**
	 * replicaSets滚动升级
	 *
	 * @param image
	 *            升级后的镜像（镜像名:镜像标签）
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult rollingReplicaSets(String proxyUrl, String namespace, String rsName, String image) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		ReplicaSet replicaSets = null;
		try {
			replicaSets = client.extensions().replicaSets().inNamespace(namespace).withName(rsName).rolling()
					.updateImage(image);
		} catch (KubernetesClientException e) {
			logger.error("资源replicaSets[" + rsName + "]升级到[" + image + "]成功: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "资源replicaSets[" + rsName + "]升级到[" + image + "]失败: " + error);
		} catch (Exception e) {
			logger.error("资源replicaSets[" + rsName + "]升级到[" + image + "]失败: ", e);
			return new BsmResult(false, "资源replicaSets[" + rsName + "]升级到[" + image + "]失败: " + e.getMessage());
		}
		if (null != replicaSets) {
			return new BsmResult(true, replicaSets, "资源replicaSets[" + rsName + "]升级到[" + image + "]成功！");
		}
		return new BsmResult(false, "资源replicaSets[" + rsName + "]升级到[" + image + "]失败！");
	}

	/**
	 * rc滚动升级
	 *
	 * @param rcName
	 *            rcName
	 * @param image
	 *            升级后的镜像（镜像名:镜像标签）
	 * @return BsmResult
	 * @author zjm
	 */
	public BsmResult rollingRc(String proxyUrl, String namespace, String rcName, String image) {
		logger.info("start rolling rc...");
		SSH ssh = null;
		ReplicationController rc = null;
		ReplicationController newRc = null;
		try {
			OpenshiftCluster cluster = openshiftClusterDao.getOpenshiftClusterByproxyUrl(proxyUrl);
			String masterIp = cluster.getMasterIp();
			String username = cluster.getUsername();
			String password = cluster.getPassword();
			ssh = new SSH(masterIp, username, password);
			rc = (ReplicationController) getRc(proxyUrl, namespace, rcName).getData();
			if (null == rc) {
				return new BsmResult(false, "资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到[" + image
						+ "]失败，获取rc name[" + rcName + "]失败");
			}

			if (ssh.connect()) {
				// 执行滚动时候增加超时时间（时间*实例数）
				String command = "oc login -u system:admin; kubectl rolling-update " + rcName + " --image=" + image
						+ " --timeout=" + k8sResourceTimeout 
						+ "s --image-pull-policy='IfNotPresent' -n " + namespace;
				logger.info("rolling rc command: \n" + command);
				String excute = ssh.executeWithResult(command);
				logger.info("rolling rc excute: \n" + excute);
				if (!excute.contains("succeeded")) {
					String error = excute.substring(excute.indexOf("error"), excute.lastIndexOf("\n"));
					logger.error("rolling update result: \n" + error);
					// 如果滚动失败则删除新启动的rc
					String newRcName = excute.substring(excute.indexOf("Scaling up ") + 11);
					newRcName = newRcName.substring(0, newRcName.indexOf(" "));
					newRc = (ReplicationController) getRc(proxyUrl, namespace, newRcName).getData();
					if (null != newRc) {
						if (!(deleteReplicationController(proxyUrl, newRc)).isSuccess()) {
							return new BsmResult(false, "资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到["
									+ image + "]失败: " + error + "新rc[" + newRc.getMetadata().getName() + "]删除失败请手动删除");
						}
					}
					// 如果滚动失败则将旧rc的实例数修改回之前的数量
					if (!(scaleRc(proxyUrl, namespace, rcName, rc.getSpec().getReplicas())).isSuccess()) {
						return new BsmResult(false,
								"资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到[" + image + "]失败: " + error
										+ "新的rc已经删除");
					}
					return new BsmResult(false, "资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到[" + image
							+ "]失败: " + error + "新的rc已经删除");
				}
				logger.info("rolling update result: \n" + excute.substring(excute.indexOf("Created ")));
			}
		} catch (Exception e) {
			logger.error("资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到[" + image + "]失败: ", e);
			return new BsmResult(false,
					"资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到[" + image + "]失败: " + e.getMessage());
		} finally {
			if (ssh != null) {
				ssh.close();
			}
		}
		if (null == rc || null != newRc) {
			return new BsmResult(false,
					"资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到[" + image + "]失败！");
		}
		logger.info("rolling rc end.");
		return new BsmResult(true, rc, "资源rc, namespace[" + namespace + "], name[" + rcName + "]升级到[" + image + "]成功！");

	}

	/**
	 * 修改deployment的资源（目前只支持cpu和memory）
	 *
	 * @param limits
	 *            值必须大于等于request
	 * @param requests
	 *            必填，数据采集使用
	 * @author zjm
	 */
	public BsmResult editDeploymentResource(String proxyUrl, String namespace, String deploymentName,
			Map<String, Quantity> limits, Map<String, Quantity> requests) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		List<Container> containers = null;
		try {
			containers = client.extensions().deployments().inNamespace(namespace).withName(deploymentName).get()
					.getSpec().getTemplate().getSpec().getContainers();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "], name[" + deploymentName + "]的deployment信息为空: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(true,
					"获取namespace[" + namespace + "], name[" + deploymentName + "]的deployment信息为空: " + error);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "], name[" + deploymentName + "]的deployment信息为空: ", e);
			return new BsmResult(true,
					"获取namespace[" + namespace + "], name[" + deploymentName + "]的deployment信息为空: " + e.getMessage());
		}
		if (ListTool.isEmpty(containers)) {
			return new BsmResult(true, "获取namespace[" + namespace + "], name[" + deploymentName + "]的deployment信息为空！");
		}
		Deployment editDeployment = null;
		for (int i = 0; i < containers.size(); i++) {
			editDeployment = client.extensions().deployments().inNamespace(namespace).withName(deploymentName).edit()
					.editSpec().editTemplate().editSpec().editContainer(i).editOrNewResources().addToLimits(limits)
					.addToRequests(requests).endResources().endContainer().endSpec().endTemplate().endSpec().done();
		}
		if (null != editDeployment) {
			return new BsmResult(true, editDeployment, "deployment[" + deploymentName + "]更新资源成功！");
		}
		return new BsmResult(false, "deployment[" + deploymentName + "]未找到！");
	}

	/**
	 * 修改rc的资源（目前只支持cpu和memory）
	 *
	 * @param limits
	 *            值必须大于等于request
	 * @param requests
	 *            必填，数据采集使用
	 * @return BsmResult
	 */
	public BsmResult editRcResource(String proxyUrl, String namespace, String rcName, Map<String, Quantity> limits,
			Map<String, Quantity> requests) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		List<Container> containers = null;
		try {
			containers = client.replicationControllers().inNamespace(namespace).withName(rcName).get().getSpec()
					.getTemplate().getSpec().getContainers();
		} catch (KubernetesClientException e) {
			logger.error("获取namespace[" + namespace + "], name[" + rcName + "]的rc信息为空: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(true, "获取namespace[" + namespace + "], name[" + rcName + "]的rc信息为空: " + error);
		} catch (Exception e) {
			logger.error("获取namespace[" + namespace + "], name[" + rcName + "]的rc信息为空: ", e);
			return new BsmResult(true,
					"获取namespace[" + namespace + "], name[" + rcName + "]的rc信息为空: " + e.getMessage());
		}
		if (ListTool.isEmpty(containers)) {
			return new BsmResult(true, "获取namespace[" + namespace + "], name[" + rcName + "]的rc信息为空！");
		}
		ReplicationController editRc = null;
		for (int i = 0; i < containers.size(); i++) {
			editRc = client.replicationControllers().inNamespace(namespace).withName(rcName).edit().editSpec()
					.editTemplate().editSpec().editContainer(i).editOrNewResources().addToLimits(limits)
					.addToRequests(requests).endResources().endContainer().endSpec().endTemplate().endSpec().done();
		}
		if (null != editRc) {
			return new BsmResult(true, editRc, "deployment[" + rcName + "]更新资源成功！");
		}
		return new BsmResult(false, "deployment[" + rcName + "]未找到！");
	}

	/**
	 * 修改rc资源名称
	 */
	public BsmResult editRcName(String proxyUrl, String namespace, String rcName, String newRcName) {
		KubernetesClient client = getKubernetesClient(proxyUrl);
		if (null == client) {
			return new BsmResult(false, "获取client[" + proxyUrl + "]连接失败！");
		}
		try {
			ReplicationController editRc = client.replicationControllers().inNamespace(namespace).withName(rcName)
					.edit().editMetadata().withName(newRcName).endMetadata().done();
			return new BsmResult(true, editRc, "资源rc[" + rcName + "]升级到[" + newRcName + "]成功！");
		} catch (KubernetesClientException e) {
			logger.error("资源rc[" + rcName + "]升级到[" + newRcName + "]成功: ", e);
			String error = getErrorInfo(e);
			return new BsmResult(false, "资源rc[" + rcName + "]升级到[" + newRcName + "]成功: " + error);
		} catch (Exception e) {
			logger.error("资源rc[" + rcName + "]升级到[" + newRcName + "]成功: ", e);
			return new BsmResult(false, "资源rc[" + rcName + "]升级到[" + newRcName + "]成功: " + e.getMessage());
		}
	}

	/**
	 * 判断rc是否健康（所有的pod是否为running）
	 */
	public BsmResult checkRcHealthy(String proxyUrl, ReplicationController rc) {
		logger.info("check rc[" + rc.getMetadata().getName() + "] healthy...");
		BsmResult bsmResult = new BsmResult();
		Map<String, String> labels = new HashMap<>();
		labels.put(DIFF_LABEL_KEY, rc.getMetadata().getLabels().get(DIFF_LABEL_KEY));
		List<Pod> pods = new ArrayList<>();

		// 每隔十秒检查一次当前rc所有的pod状态，如果全部running则表示健康跳出循环，
		// 如果到达超时时间还没有全部running，则代表不健康结束循环
		for (int time = 0; time <= k8sResourceTimeout; time += 10) {
			// 统计pod running的数量
			int podRunning = 0;
			// 每次循环休息十秒钟
			try {
				Thread.sleep(10 * 1000);
			} catch (InterruptedException e) {
				logger.error("rc[" + rc.getMetadata().getName() + "] unhealthy");
				bsmResult.setMessage("检查rc状态失败！");
				return bsmResult;
			}
			TwoTuple<List<Pod>, String> twoTuple = getPods(proxyUrl, labels);
			if (twoTuple.second != null) {
				bsmResult.setMessage(twoTuple.second);
				return bsmResult;
			}
			pods = twoTuple.first;
			for (Pod pod : pods) {
				Integer restartCount = 0;
				String status;
				List<String> statuss = new ArrayList<>();
				// 循环pod里所有容器的状态及其其它信息
				String reason = pod.getStatus().getReason();
				// pod.getStatus().getReason()有值，一般是环境原因导致，比如node节点丢失
				if (org.springframework.util.StringUtils.hasText(reason)) {
					statuss.add(reason);
				} else {
					// 统计container running的数量
					int containerRunning = 0;
					List<ContainerStatus> containerStatuses = pod.getStatus().getContainerStatuses();

					// pod的容器无状态的时候
					if (ListTool.isEmpty(containerStatuses)) {
						status = "Pending";
						statuss.add(status);
					} else {// pod的容器有状态的时候
						for (ContainerStatus containerStatus : containerStatuses) {
							if (containerStatus.getRestartCount() >= restartCount) {
								restartCount = containerStatus.getRestartCount();
								ContainerStateWaiting waiting = containerStatus.getState().getWaiting();
								if (waiting != null) {
									status = waiting.getReason();
								} else {
									if (containerStatus.getState().getRunning() != null) {
										// 如果容器状态为running，则累计pod的健康数量
										status = "running";
										containerRunning++;
									} else if (null != containerStatus.getState().getTerminated()
											&& org.springframework.util.StringUtils
													.hasText(containerStatus.getState().getTerminated().getReason())) {
										status = containerStatus.getState().getTerminated().getReason();
									} else {
										status = "Terminating";
									}
								}
								statuss.add(status);
							}
						}
					}
					if (!ListTool.isEmpty(containerStatuses) && containerRunning == containerStatuses.size()) {
						podRunning++;
					}
				}
			}
			if (podRunning == pods.size()) {
				logger.info("rc[" + rc.getMetadata().getName() + "] healthy");
				return new BsmResult(true, "rc [" + rc.getMetadata().getName() + "]状态为健康！");
			}
		}
		logger.info("rc[" + rc.getMetadata().getName() + "] unhealthy");
		return new BsmResult(false, "rc [" + rc.getMetadata().getName() + "]状态为不健康！");
	}

	/**
	 * 判断rc是否运行（如果超时时间内有任何一个pod是running状态则该rc正在运行）
	 */
	public BsmResult checkRcRunning(String proxyUrl, ReplicationController rc) {
		logger.info("检查rc[" + rc.getMetadata().getName() + "]运行状态...");
		BsmResult bsmResult = new BsmResult();
		Map<String, String> labels = new HashMap<String, String>();
		labels.put(DIFF_LABEL_KEY, rc.getMetadata().getLabels().get(DIFF_LABEL_KEY));
		// 如果失败将所有pod存起来用于获取信息
		List<Pod> pods = null;

		// 每隔十秒钟检查一次当前rc所有的pod状态，如果有任何pod状态是running则表示rc正在运行跳出循环，
		// 如果到达超时时间还没有全部running，则代表rc运行失败结束循环
		for (int time = 0; time <= k8sResourceTimeout; time += 10) {
			// 每次循环休息十秒
			try {
				Thread.sleep(10 * 1000);
			} catch (InterruptedException e) {
				bsmResult.setMessage("检查rc状态失败！");
				return bsmResult;
			}
			TwoTuple<List<Pod>, String> twoTuple = getPods(proxyUrl, labels);
			if (twoTuple.second != null) {
				bsmResult.setMessage(twoTuple.second);
				return bsmResult;
			}

			for (Pod pod : twoTuple.first) {
				Integer restartCount = 0;
				String status;
				List<String> statuss = new ArrayList<>();
				// 循环pod里所有容器的状态及其其它信息
				String reason = pod.getStatus().getReason();
				// pod.getStatus().getReason()有值，一般是环境原因导致，比如node节点丢失
				if (org.springframework.util.StringUtils.hasText(reason)) {
					statuss.add(reason);
				} else {
					// 统计container running的数量
					int containerRunning = 0;
					List<ContainerStatus> containerStatuses = pod.getStatus().getContainerStatuses();

					// pod的容器无状态的时候
					if (ListTool.isEmpty(containerStatuses)) {
						status = "Pending";
						statuss.add(status);
					} else {// pod的容器有状态的时候
						for (ContainerStatus containerStatus : containerStatuses) {
							if (containerStatus.getRestartCount() >= restartCount) {
								restartCount = containerStatus.getRestartCount();
								ContainerStateWaiting waiting = containerStatus.getState().getWaiting();
								if (waiting != null) {
									status = waiting.getReason();
								} else {
									if (containerStatus.getState().getRunning() != null) {
										// 如果容器状态为running，则累计pod的健康数量
										status = "running";
										containerRunning++;
									} else if (null != containerStatus.getState().getTerminated()
											&& org.springframework.util.StringUtils
													.hasText(containerStatus.getState().getTerminated().getReason())) {
										status = containerStatus.getState().getTerminated().getReason();
									} else {
										status = "Terminating";
									}
								}
								statuss.add(status);
							}
						}
					}
					if (!ListTool.isEmpty(containerStatuses) && containerRunning == containerStatuses.size()) {
						bsmResult.setMessage("rc [" + rc.getMetadata().getName() + "]正在运行...");
						bsmResult.setSuccess(true);
						logger.info(bsmResult.getMessage());
						return bsmResult;
					}
				}
			}
			pods = twoTuple.first;
		}
		bsmResult.setMessage("rc [" + rc.getMetadata().getName() + "]运行超时！");
		bsmResult.setData(pods);
		logger.error(bsmResult.getMessage());
		return bsmResult;
	}

	/**
	 * 判断rc所有pod是否可正常访问，如果rc的ReadyReplicas等于rc的Replicas表示rc所有pod可正常访问
	 */
	public BsmResult checkRcReady(String proxyUrl, ReplicationController rc) {
		logger.info("检查rc[" + rc.getMetadata().getName() + "]运行状态...");
		BsmResult bsmResult = new BsmResult();
		Map<String, String> labels = new HashMap<String, String>();
		labels.put(DIFF_LABEL_KEY, rc.getMetadata().getLabels().get(DIFF_LABEL_KEY));
		// 如果失败将所有pod存起来用于获取信息
		List<Pod> pods = null;

		// 每隔十秒钟检查一次当前rc所有的pod状态，如果有任何pod状态是running则表示rc正在运行跳出循环，
		// 如果到达超时时间还没有全部running，则代表rc运行失败结束循环
		for (int time = 0; time <= k8sResourceTimeout; time += 10) {
			Integer podCount = 0;
			// 每次循环休息十秒
			try {
				Thread.sleep(10 * 1000);
			} catch (InterruptedException e) {
				bsmResult.setMessage("检查rc状态失败！");
				return bsmResult;
			}
			TwoTuple<List<Pod>, String> twoTuple = getPods(proxyUrl, labels);
			if (twoTuple.second != null) {
				bsmResult.setMessage(twoTuple.second);
				return bsmResult;
			}

			for (Pod pod : twoTuple.first) {
				Integer readyCount = 0;
				// 循环pod里所有容器的状态及其其它信息
				String reason = pod.getStatus().getReason();
				// pod.getStatus().getReason()有值，一般是环境原因导致，比如node节点丢失
				if (!org.springframework.util.StringUtils.hasText(reason)) {
					List<ContainerStatus> containerStatuses = pod.getStatus().getContainerStatuses();
					// pod的容器无状态的时候
					if (!ListTool.isEmpty(containerStatuses)) {
						for (ContainerStatus containerStatus : containerStatuses) {
							if (containerStatus.getReady()) {
								readyCount ++;
							}
						}
						if (readyCount.equals(containerStatuses.size())) {
							podCount ++;
						}
					}
				}
			}
			pods = twoTuple.first;
			if (pods.size() > 0 && podCount.equals(pods.size())) {
				bsmResult.setMessage("rc[" + rc.getMetadata().getName() + "]运行成功！");
				logger.info(bsmResult.getMessage());
				bsmResult.setSuccess(true);
				return bsmResult;
			}
		}
		bsmResult.setData(pods);
		bsmResult.setMessage("rc [" + rc.getMetadata().getName() + "]运行超时！");
		logger.error(bsmResult.getMessage());
		return bsmResult;
	}

	// 复制rc
	public ReplicationController cloneRc(String proxyUrl, ReplicationController rc, String image, String newRcName) {
		if (null == rc) {
			return null;
		}
		Container updatedContainer = new ContainerBuilder(
				rc.getSpec().getTemplate().getSpec().getContainers().iterator().next()).withImage(image).build();

		ReplicationControllerBuilder newRCBuilder = new ReplicationControllerBuilder(rc);
		String diffLabelValue = newRCBuilder.build().getMetadata().getLabels().get(OpenshiftUtil.UNIFIED_LABEL_KEY)
				+ "-" + RandomStringUtils.randomAlphanumeric(7).toLowerCase();
		Map<String, String> labels = new HashMap<String, String>();
		labels.put(DIFF_LABEL_KEY, diffLabelValue);
		newRCBuilder.editMetadata().withResourceVersion(null).withName(newRcName).removeFromLabels(DIFF_LABEL_KEY)
				.addToLabels(labels).endMetadata().editSpec().editTemplate().editSpec()
				.withContainers(Collections.singletonList(updatedContainer)).endSpec().editMetadata()
				.removeFromLabels(DIFF_LABEL_KEY).addToLabels(labels).endMetadata().endTemplate()
				.removeFromSelector(DIFF_LABEL_KEY).addToSelector(labels).endSpec();
		logger.info("rc[" + rc.getMetadata().getName() + "]克隆[" + newRcName + "]成功");
		return newRCBuilder.build();
	}

	@SuppressWarnings("unused")
	private String md5sum(HasMetadata obj) throws NoSuchAlgorithmException, JsonProcessingException {
		byte[] digest = MessageDigest.getInstance("MD5").digest(dumpWithoutRuntimeStateAsYaml(obj).getBytes());
		BigInteger i = new BigInteger(1, digest);
		return String.format("%1$032x", i);
	}

	public static void main(String[] args) {
		// String appName = "yyy";
		// String proxyUrl = "https://master.example.com:8443/";
		// Config config = new ConfigBuilder().withMasterUrl(proxyUrl).build();
		// config.setTrustCerts(true);
		// config.setOauthToken("ZXlKaGJHY2lPaUpTVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUp0WVc1aFoyVnRaVzUwTFdsdVpuSmhJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbTFoYm1GblpXMWxiblF0WVdSdGFXNHRkRzlyWlc0dE1UZGpjSEVpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pYldGdVlXZGxiV1Z1ZEMxaFpHMXBiaUlzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG5WcFpDSTZJbUl5TnpJeFlUUTNMV05pT0RJdE1URmxOeTFoTWpNekxUQXdOVEExTmpnell6azVNQ0lzSW5OMVlpSTZJbk41YzNSbGJUcHpaWEoyYVdObFlXTmpiM1Z1ZERwdFlXNWhaMlZ0Wlc1MExXbHVabkpoT20xaGJtRm5aVzFsYm5RdFlXUnRhVzRpZlEuRWhuUTJVNEV0Qk1WaXN0MWNGeTRJSjBYNXM5WW05bTRjZkU1SEdMTHo0eVYzWnN4cnNIRnhBS3VZTlo0RHVZa1ZoWkxPb3NzMFkwbVFXN0FzRWNLNWRjUWNMbGJrTlk0Z2dWLUVReGlyV29nQi1wa1lpdkFsS004eWthLTdpV2dxZVU1dFNJQTJDTzRxNEUybmJ0eG9ZWG8yeWJMcWdWZVNrVFFBWlJmZFdDOUZpeXQ1NnJHc3dEeDY5dWdlaHg4dTEyMjVjSHVjd0htM1pfTGpUd0NuQkN2T2hXUEhLM1hHSjRac0hhWFhKWjBpdS1ZTEp5NUwyME1vaTBZLTNGaVVROHh5NXFRQ1dPd01haFpIYks1VDlJVHdTeklNU3RiaEVleXlJVFAwWWhpXzladjZYNzVxTE1Bd0ZRLWFkRnhMV2dGMGR5VnJGUGcxeVdSdUFEOHNR");
		// KubernetesClient client = new DefaultOpenShiftClient(config);
		// List<Service> services =
		// client.services().inNamespace("default").list().getItems();
		// for (Service service : services) {
		// if (service.getSpec().getSelector() != null &&
		// service.getSpec().getSelector().containsKey("app")) {
		// if (service.getSpec().getSelector().containsValue("myweb")) {
		// SSH ssh = new SSH("192.168.1.61", "root", "onceas");
		// try {
		// if (ssh.connect()) {
		// String excute = ssh.executeWithResult("oc login -u system:admin; oc
		// export svc myweb -o yaml");
		// String serviceYaml = excute.substring(excute.indexOf("apiVersion:
		// "));
		// client.services().delete(service);
		// Thread.sleep(1000*60*3);
		// try {
		// // 最终需要添加的资源
		// List<HasMetadata> hasMetadatas = new ArrayList<>();
		// // 获取文件中资源
		// List<HasMetadata> resourceList = client.load(new
		// ByteArrayInputStream(serviceYaml.getBytes())).get();
		// // 设置label value追加的日期和随机字符串
		// String diffLabelValue = "-" +
		// RandomStringUtils.randomAlphanumeric(7).toLowerCase();
		// for (HasMetadata resource : resourceList) {
		// // 判断资源的命名空间是否存在，如果不存在则创建这个命名空间
		// Map<String, String> labels = resource.getMetadata().getLabels();
		// if (null == labels) {
		// labels = new HashMap<>();
		// }
		// // 追加资源标签
		// labels.put(UNIFIED_LABEL_KEY, appName);
		// labels.put(DIFF_LABEL_KEY, appName + diffLabelValue);
		// // 如果资源是rc或者deployment则给资源中的pod追加label
		// if ("ReplicationController".equals(resource.getKind())) {
		// ReplicationController replicationController = (ReplicationController)
		// resource;
		// // 判断编排文件中是否包含已经存在的资源，如果存在则不允许创建
		// Map<String, String> podLabels =
		// replicationController.getSpec().getTemplate().getMetadata()
		// .getLabels();
		// if (null == podLabels) {
		// podLabels = new HashMap<>();
		// }
		// // 追加资源标签
		// podLabels.put(UNIFIED_LABEL_KEY, appName);
		// podLabels.put(DIFF_LABEL_KEY, appName + diffLabelValue);
		// } else if ("Service".equals(resource.getKind())) {
		// Service service1 = (Service) resource;
		// Map<String, String> selectors = service1.getSpec().getSelector();
		// selectors.put(DIFF_LABEL_KEY, appName + diffLabelValue);
		// } else if ("HorizontalPodAutoscaler".equals(resource.getKind())) {
		// } else {
		// }
		// hasMetadatas.add(resource);
		// }
		// resourceList = client.resourceList(hasMetadatas).createOrReplace();
		// } catch (Exception e) {
		// logger.error("发布应用失败: ", e);
		// }
		// }
		// } catch (Exception e) {
		// // TODO: handle exception
		// }
		//// client.services().createOrReplace(service);
		// }
		// }
		// }
		// client.close();
		try {
			String proxyUrl = "https://master.example.com:8443/";
			Config config = new ConfigBuilder().withMasterUrl(proxyUrl).build();
			config.setTrustCerts(true);
			config.setOauthToken(
					"ZXlKaGJHY2lPaUpTVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUp0WVc1aFoyVnRaVzUwTFdsdVpuSmhJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbTFoYm1GblpXMWxiblF0WVdSdGFXNHRkRzlyWlc0dE1UZGpjSEVpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pYldGdVlXZGxiV1Z1ZEMxaFpHMXBiaUlzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG5WcFpDSTZJbUl5TnpJeFlUUTNMV05pT0RJdE1URmxOeTFoTWpNekxUQXdOVEExTmpnell6azVNQ0lzSW5OMVlpSTZJbk41YzNSbGJUcHpaWEoyYVdObFlXTmpiM1Z1ZERwdFlXNWhaMlZ0Wlc1MExXbHVabkpoT20xaGJtRm5aVzFsYm5RdFlXUnRhVzRpZlEuRWhuUTJVNEV0Qk1WaXN0MWNGeTRJSjBYNXM5WW05bTRjZkU1SEdMTHo0eVYzWnN4cnNIRnhBS3VZTlo0RHVZa1ZoWkxPb3NzMFkwbVFXN0FzRWNLNWRjUWNMbGJrTlk0Z2dWLUVReGlyV29nQi1wa1lpdkFsS004eWthLTdpV2dxZVU1dFNJQTJDTzRxNEUybmJ0eG9ZWG8yeWJMcWdWZVNrVFFBWlJmZFdDOUZpeXQ1NnJHc3dEeDY5dWdlaHg4dTEyMjVjSHVjd0htM1pfTGpUd0NuQkN2T2hXUEhLM1hHSjRac0hhWFhKWjBpdS1ZTEp5NUwyME1vaTBZLTNGaVVROHh5NXFRQ1dPd01haFpIYks1VDlJVHdTeklNU3RiaEVleXlJVFAwWWhpXzladjZYNzVxTE1Bd0ZRLWFkRnhMV2dGMGR5VnJGUGcxeVdSdUFEOHNR");
			KubernetesClient client = new DefaultOpenShiftClient(config);
			ReplicationController rc = client.replicationControllers().inNamespace("test").withName("tom-full").get();
			System.out.println(rc.getStatus().getReadyReplicas());
			System.out.println(null != rc.getStatus().getReadyReplicas()
					&& rc.getStatus().getReadyReplicas().equals(rc.getSpec().getReplicas()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
